import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
import java.io.FileReader;


//runs the downlaod from peer to peer
public class dThread extends Thread{
	private Socket sock=null;
	BufferedReader input;
	String dl="";
	saperePeer main=null;
	
	public dThread(Socket socket, saperePeer s)
	{
		super("dThread");
		this.sock = socket;
		this.main = s;
		System.out.println("Connection received from " + sock.getInetAddress().getHostAddress());
		Peer newP = new Peer();
		newP.ipAddress = sock.getInetAddress();
		newP.superPeer = false; // set to false until we implement superpeer code
		newP.throughput = 0; // set to 0 until we implement superpeer code
		//do not use the socket in the peer object since that is only for clients to use
		main.addPeer(newP);
	}
	
	public static byte[] hexToByte(String s) {
	    int len = s.length();
	    byte[] data = new byte[len / 2];
	    for (int i = 0; i < len; i += 2) {
	        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
	                             + Character.digit(s.charAt(i+1), 16));
	    }
	    return data;
	}
	
	public void run()
	{
		try{
			PrintWriter out = new PrintWriter(sock.getOutputStream(),true);
		    BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));

		    String inputLine;
		    Scanner s = null;
		    String cType = "";
		    String curDir = System.getProperty("user.dir");
		    
		    while ((inputLine = in.readLine()) != null) {
		    	System.out.println(inputLine);
		    	s = new Scanner(inputLine).useDelimiter("\\s*;\\s*");
		    	while(s.hasNext())
		    	{
		    		cType=s.next();
		    		if(cType.equals("download:class:aFile"))
		    		{
		    			aFile newF = new aFile();
		    			newF.name = s.next();
		    			this.input =  new BufferedReader(new FileReader(curDir+"\\share\\"+newF.name));
		    			newF.size = Integer.parseInt(s.next());
		    			newF.Peer = s.next();
		    			newF.shortAbstract = s.next();
		    			//newF.setHash(hexToByte(s.next()));
		    			//if(!newF.Peer.equals(InetAddress.getLocalHost().getHostAddress()))
		    			//	out.println("File not found");
		    			//else
		    		//	{
		    				while((dl=input.readLine())!=null)
		    					out.println(dl);
		    				out.println(";done;");
		    			//}
		    				input.close();
		    				
		    		}
		    		else if(cType.equals("class:aFile"))
		    		{
		    			//add a new file that the user can search
		    			aFile newF = new aFile();
		    			newF.name = s.next();
		    			newF.size = Integer.parseInt(s.next());
		    			newF.Peer = s.next();
		    			newF.shortAbstract = s.next();
		    			newF.setHash(hexToByte(s.next()));
		    			//probably need to check that this is a new aFile
		    			//i.e. has not been uploaded already
		    			main.addFile(newF);
		    		}
		    		else if(cType.equals("class:Search"))
		    		{
		    			//format the search and pass to the main function
		    			Search newS = new Search(s.next());
		    			newS.searchHash = hexToByte(s.next());
		    			//send the search results back to the user
		    			System.out.println("Starting Search: "+newS.sText);
		    			//need to make a search function for the peer client
		    			//out.println(main.search(newS));
		    			out.println(this.main.searchFileSpace(newS));
		    			out.println("done");;
		    		}
		    		else if(cType.equals("peerToSuper:class:Search"))
		    		{
		    			//format the search and pass to the main function
		    			String result="";
		    			Search newS = new Search(s.next());
		    			newS.searchHash = hexToByte(s.next());
		    			//send the search results back to the user
		    			System.out.println("Starting Search: "+newS.sText);
		    			//need to make a search function for the peer client
		    			//out.println(main.search(newS));
		    			main.searchHere(newS, false);
		    			try {
							this.sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
		    			for(int i =0;i<main.searchResult.size();i++)
		    			{
		    				result += main.searchResult.get(i).toString()
							+ byteToHex(main.searchResult.get(i).getHash()) + "\n";
		    			}
		    			System.out.println(result);
		    			out.println(result);
		    			out.println("done");
		    		}
		    	
		    	}

		    	if (inputLine.equals("Quit"))
		    	{
		    		System.out.println("Connection Ended from " + sock.getInetAddress().getHostAddress());
		    		break;
		    	}
		    		
		    	}
	    out.close();
	    in.close();
	    sock.close();
	    //input.close();
	} catch (IOException e) {
	    e.printStackTrace();
	}
	}
	
	static String byteToHex(byte[] msg) {
		String result = "";
		for (int i = 0; i < msg.length; i++) {
			char highBits, LowBits;
			highBits = (char) ((msg[i] >>> 4) & 0xf);
			LowBits = (char) (msg[i] & 0xf);
			highBits = (char) ((highBits > 9) ? 'A' + (highBits - 10)
					: '0' + highBits);
			LowBits = (char) ((LowBits > 9) ? 'A' + (LowBits - 10)
					: '0' + LowBits);
			result += highBits;
			result += LowBits;
		}
		return result;
	}
}
